#include <string>
#include <iostream>
#include "stdio.h"

#include "sql.h"
#include "sqlext.h"
#include "sqltypes.h"

using namespace std;

const char* DSN  = "sqws138";  //"sq169";
const char* UID  = "sql_user"; //"sql_user1";
const char* PASS = "redhat06"; //"sq2010";

void ListDSN(SQLHENV henv) {
   char l_dsn[256],l_desc[256];
   short int l_len1,l_len2,l_next;

   cout<<"list all dsn:"<<endl;
   l_next=SQL_FETCH_FIRST;
   while (SQLDataSources(henv, l_next, (SQLCHAR*)l_dsn, 256, &l_len1, 
                                       (SQLCHAR*)l_desc, 256, &l_len2) 
          == SQL_SUCCESS) {
         cout << "Server=(" << l_dsn << "), Description=(" << l_desc << ")\n";
         l_next=SQL_FETCH_NEXT;
   }
}

SQLRETURN odbcInit(SQLHENV &henv, SQLHDBC &hdbc, SQLHSTMT &hstmt) {

   cout << "SQLAllocHandle (SQL_HANDLE_ENV,SQL_NULL_HANDLE,&henv)" << endl;
   SQLRETURN herr = SQLAllocHandle(SQL_HANDLE_ENV,SQL_NULL_HANDLE,&henv);
   if ((herr != SQL_SUCCESS) && (herr != SQL_SUCCESS_WITH_INFO))
      return herr;
   else
      cout<<"Succeed"<<endl;

   ListDSN(henv);
   cout << "SQLSetEnvAttr (henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0)"
        << endl;
   herr = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
   if ( (herr != SQL_SUCCESS) && (herr != SQL_SUCCESS_WITH_INFO) ) {
      SQLFreeHandle(SQL_HANDLE_ENV, henv);
      return herr;
   }
   else
      cout << "Succeed" << endl;

    // 2. allocate connection handle, set timeout
   cout << "SQLAllocHandle (SQL_HANDLE_DBC, henv, &hdbc)" << endl; 
   herr = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); 
   if ( (herr != SQL_SUCCESS) && (herr != SQL_SUCCESS_WITH_INFO) ) {
      SQLFreeHandle(SQL_HANDLE_ENV, henv);
      return herr;
   }
   else
      cout << "Succeed" << endl;

   // 3. Connect to the datasource 
   cout << "SQLConnect (hdbc, (SQLCHAR*)DSN, SQL_NTS, "
        << "(SQLCHAR*)UID, SQL_NTS, (SQLCHAR*)PASS, SQL_NTS)"<<endl;

   cout << DSN << ", " << UID << ", " << PASS << endl;

   herr = SQLConnect(hdbc, (SQLCHAR*)DSN, SQL_NTS,
                           (SQLCHAR*)UID, SQL_NTS,
                           (SQLCHAR*)PASS, SQL_NTS);

   if ( (herr != SQL_SUCCESS) && (herr != SQL_SUCCESS_WITH_INFO) ) {
      SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
      SQLFreeHandle(SQL_HANDLE_ENV, henv);
      return herr;
   }
   else
      cout<<"Succeed"<<endl;

   // 4. Alloc statement handle
   cout << "SQLAllocHandle (SQL_HANDLE_STMT, hdbc, &hstmt)" << endl;
   herr=SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
   if ((herr != SQL_SUCCESS) && (herr != SQL_SUCCESS_WITH_INFO)) {
      SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
      SQLFreeHandle(SQL_HANDLE_ENV, henv);
      return herr;
   }
   else
      cout << "Succeed" << endl;
 
   return herr;
}

void odbcFree(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt) {
   SQLFreeHandle(SQL_HANDLE_STMT,hstmt);
   SQLDisconnect(hdbc);
   SQLFreeHandle(SQL_HANDLE_DBC,hdbc);
   SQLFreeHandle(SQL_HANDLE_ENV, henv);
}

SQLRETURN runSql() {
   SQLHENV henv = SQL_NULL_HANDLE;
   SQLHDBC hdbc = SQL_NULL_HANDLE;
   SQLHSTMT hstmt = SQL_NULL_HANDLE;

   SQLRETURN herr = odbcInit(henv, hdbc, hstmt);
   if ((herr != SQL_SUCCESS) && (herr != SQL_SUCCESS_WITH_INFO)) {
      cout<<"Init failed"<<endl;
      return herr;
   }
 
   string sqlcmd;

   /*
      create table odbc_test (id int not null primary key, 
                              text varchar (32));
   */

   sqlcmd = "delete from neo.usr.odbc_test";
   herr = SQLExecDirect(hstmt, (SQLCHAR*)sqlcmd.c_str(), sqlcmd.size());

   for(int i = 0; i< 15; i++) {
       char buf[256];
       sprintf(buf, " (%d, 'ccd_%d');", i, i);
       sqlcmd = "insert into neo.usr.odbc_test values";
       sqlcmd += buf;

       herr = SQLExecDirect(hstmt, (SQLCHAR*)sqlcmd.c_str(), sqlcmd.size());
       if ((herr != SQL_SUCCESS) && (herr != SQL_SUCCESS_WITH_INFO)) {
           cout<<"Insert failed"<<endl;
           return herr;
        }
   }

//   sqlcmd = "select * from manageability.instance_repository.health_overview_1";
//   herr = SQLExecDirect(hstmt, (SQLCHAR*)sqlcmd.c_str(), sqlcmd.size());
   odbcFree(henv, hdbc, hstmt);

   return SQL_SUCCESS;
}

int main()
{
   return runSql();
}

